package uk.ac.manchester.tewpl.iceiface.client.explorer.ui;

import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;

import uk.ac.manchester.tewpl.iceiface.client.Functors.VoidCallback;
import uk.ac.manchester.tewpl.iceiface.client.explorer.Explorer;
import uk.ac.manchester.tewpl.iceiface.client.explorer.FilterResult;
import uk.ac.manchester.tewpl.iceiface.client.explorer.Utils;
import uk.ac.manchester.tewpl.iceiface.client.explorer.events.ExplorerEvent;
import uk.ac.manchester.tewpl.iceiface.client.explorer.nodes.Airport;
import uk.ac.manchester.tewpl.iceiface.client.explorer.nodes.Terminal;
import uk.ac.manchester.tewpl.iceiface.client.explorer.types.Mutable;
import uk.ac.manchester.tewpl.iceiface.client.explorer.types.Route;
import uk.ac.manchester.tewpl.iceiface.client.model.KBIndividualModel;

import com.extjs.gxt.ui.client.Registry;
import com.extjs.gxt.ui.client.Style.LayoutRegion;
import com.extjs.gxt.ui.client.core.XTemplate;
import com.extjs.gxt.ui.client.data.BaseModelData;
import com.extjs.gxt.ui.client.event.ButtonEvent;
import com.extjs.gxt.ui.client.event.SelectionListener;
import com.extjs.gxt.ui.client.store.GroupingStore;
import com.extjs.gxt.ui.client.util.Margins;
import com.extjs.gxt.ui.client.widget.ContentPanel;
import com.extjs.gxt.ui.client.widget.Text;
import com.extjs.gxt.ui.client.widget.Window;
import com.extjs.gxt.ui.client.widget.button.Button;
import com.extjs.gxt.ui.client.widget.form.Radio;
import com.extjs.gxt.ui.client.widget.form.RadioGroup;
import com.extjs.gxt.ui.client.widget.grid.ColumnConfig;
import com.extjs.gxt.ui.client.widget.grid.ColumnModel;
import com.extjs.gxt.ui.client.widget.grid.Grid;
import com.extjs.gxt.ui.client.widget.grid.GridGroupRenderer;
import com.extjs.gxt.ui.client.widget.grid.GroupColumnData;
import com.extjs.gxt.ui.client.widget.grid.GroupingView;
import com.extjs.gxt.ui.client.widget.grid.RowExpander;
import com.extjs.gxt.ui.client.widget.layout.BorderLayoutData;
import com.extjs.gxt.ui.client.widget.layout.FitLayout;
import com.extjs.gxt.ui.client.widget.toolbar.FillToolItem;
import com.extjs.gxt.ui.client.widget.toolbar.LabelToolItem;
import com.extjs.gxt.ui.client.widget.toolbar.ToolBar;

public class ResultsPanel extends UI {
	
	// Explorer
	private Explorer explorer;
	
	// Initialisation variables
	private boolean initialised = false;
	
	// Retrieve variables
	private Collection<Airport> airports = Registry.get("airports");
	private Mutable<Airport> airportSelected = Registry.get("airportSelected");
	private LinkedList<Airport> journey = Registry.get("journey");
	private ArrayList<KBIndividualModel> timePeriods = Registry.get("timePeriods");
	private Utils utils = Registry.get("utils");
	
	// Data grid variables
	GroupingStore<BaseModelData> dataStore;
	
	public ResultsPanel (Explorer expl) {
		explorer = expl;
		// Configure panel
		this.setHeaderVisible(false);
		
		// Results panel toolbar
		ToolBar resultsToolBar = new ToolBar();		
		
		// Report button
		Button reportButton = new Button("Create Report", new SelectionListener<ButtonEvent>() {
			@Override
			public void componentSelected(ButtonEvent ce) {
				Window w = new Window();
				w.setSize(200, 200);
				w.add(new Text("Report window"));
				w.show();
			}
		});
		
		resultsToolBar.add(reportButton);
		
		// Radio boxes
		Radio allView = new Radio();
		allView.setBoxLabel("All");
		allView.setValue(true);
		
		Radio orphanView = new Radio();
		orphanView.setBoxLabel("Orphans");
		orphanView.setValue(false);
		
		RadioGroup viewSelection = new RadioGroup();
		viewSelection.add(allView);
		viewSelection.add(orphanView);
		
		resultsToolBar.add(new FillToolItem());
		resultsToolBar.add(new LabelToolItem("Show:"));
		resultsToolBar.add(viewSelection);
		
		this.setTopComponent(resultsToolBar);
		
		/*
		 * GRID code
		 */
		
		//tabPanel.setSelection(resultsTab);
		
		// Test data
		/*List<BaseModelData> data = new ArrayList<BaseModelData>();
		for (int i=0; i<30; i++) {
			java.util.Map<String, Object> props = new HashMap<String, Object>();
			props.put("label", "result1");
			if (i<5)
				props.put("terminal", "T1");
			else if (i < 10)
				props.put("terminal", "T2");
			else if (i < 15)
				props.put("terminal", "T3");
			else if (i < 20)
				props.put("terminal", "T4");
			else if (i < 25)
				props.put("terminal", "T5");
			else 
				props.put("airport", "T6");
			data.add(new BaseModelData(props));
		}*/
		
		// Set up row expander
		RowExpander expander = new RowExpander();
		expander.setTemplate(XTemplate.create("<p><b>Properties<b>:{props}"));
		
		// Set up columns
		ColumnConfig column = new ColumnConfig("label", "Label", 200);
		ColumnConfig column2 = new ColumnConfig("description", "Description", 300);
		ColumnConfig column3 = new ColumnConfig("terminal", "Terminal", 200);
		
		// Create column collection
		List<ColumnConfig> configs = new ArrayList<ColumnConfig>();
		configs.add(expander);
		configs.add(column);
		configs.add(column2);
		configs.add(column3);
		
		// Set column model
		final ColumnModel cm = new ColumnModel(configs);
		
		// Set store model
		dataStore = new GroupingStore<BaseModelData>();
		dataStore.groupBy("terminal");
		
		// GroupingView
		GroupingView view = new GroupingView();
		view.setForceFit(true); // Try and prevent horizontal scrolling
		view.setStartCollapsed(false);
		view.setShowGroupedColumn(false);
		
		// Add group count
		view.setGroupRenderer(new GridGroupRenderer() {
			@Override
			public String render(GroupColumnData data) {
				String str;
				
				if (data.group == "")
					str =  "At Airport ";
				else
					str = "At terminal: " + data.group;
				
				str += " (" + data.models.size() + " results)";
				return str;
			}
		});
		
		Grid<BaseModelData> grid = new Grid<BaseModelData>(dataStore, cm);
		//grid.setHideHeaders(true);
		grid.setView(view);
		grid.addPlugin(expander); 
		this.setLayout(new FitLayout());
		this.add(grid);
		
		//dataStore.add(data);
		
	}

	@Override
	public void init(VoidCallback onFinishCallback) {
		//explorer.mask("Initialising results panel...");
		initialised = true;
		onFinishCallback.work();
	}

	@Override
	public void handle(ExplorerEvent event) {
		/*switch(event) {
		case RESET:
		case INIT:
		case CHANGE_JOURNEY:
		case CHANGE_SELECTED_AIRPORT:
		}*/
	}
	
//	/*
//	 * Adaptor between FilterResult[] and DataStore
//	 */
//	private void populateDataGrid(Airport airport) {
//		// If a filter has been applied and there are results
//		if (airport.getCount() > 0) {
//
//			// Adaptor for Grid
//			ArrayList<java.util.Map<String, Object>> gridResults = new ArrayList<java.util.Map<String,Object>>();
//			//for (Airport airport : airports) { // for each airoprt
//				
//				if (airport.getFilterResults() != null) {
//					// For each individual
//					for (FilterResult result : airport.getFilterResults()) {
//						HashMap<String, Object> map;
//						// Read data values from each individual into map for grid
//						map = new HashMap<String, Object>();
//						//map.put("airport", airport.getLabel());
//						map.put("terminal", "");
//						map.put("label", result.getIndividual().getLabel());
//						map.put("description", result.getIndividual().getDescription());
//						map.put("props", "" + (result.getProperties() == null ? "none" : result.getProperties().toString()));
//						gridResults.add(map);
//					} // for
//				}
//				
//				// For each terminal
//				if (airport.getTerminals() != null) {
//					for (Terminal terminal : airport.getTerminals()) {
//						// For each individual
//						if (terminal.getFilterResults() != null) {
//							for (FilterResult result : terminal.getFilterResults()) {
//								HashMap<String, Object> map;
//								// Read data values from each individual into map for grid
//								map = new HashMap<String, Object>();
//								map.put("label", result.getIndividual().getLabel());
//								map.put("description", result.getIndividual().getDescription());
//								map.put("terminal", terminal.getLabel());
//								map.put("props", "" + (result.getProperties() == null ? "none" : result.getProperties().toString()));
//								gridResults.add(map);
//							} // for
//						} // if
//					} // for
//				} // if
//			//} // for
//			
//			dataStore.removeAll();
//			
//			// Migrate map to data store
//			List<BaseModelData> data = new ArrayList<BaseModelData>();
//			
//			for (java.util.Map<String, Object> map : gridResults) {
//				data.add(new BaseModelData(map));
//			}
//			
//			dataStore.add(data);
//			
//		} else { // If no results
//			dataStore.removeAll();
//		}
//	} // populateDataGrid

}
